/*
 * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
 */

var pages=[],
	ref=[],
	firstLink = null,
	firstLinkWord = null,
	g_word = "",	// remember last selected word
	g_highlight = "",
	g_searchValue = "",
	g_mcase = false,
	g_n = navigator,
	g_nUA = g_n.userAgent,
	// do these once only
	g_isFirefox = g_nUA.indexOf("Firefox/") != -1,
	g_isMSIE = g_nUA.indexOf("MSIE") != -1,
	g_IE7orBelow = (parseFloat(g_n.appVersion.split("MSIE ")[1]) <= 7) || undefined,
	g_isOpera = g_nUA.indexOf("Opera") != -1,
	g_isNetscape = g_nUA.indexOf("Netscape/") != -1,
	g_isMozilla = !(g_isFirefox || g_isMSIE || g_isNetscape);
g_n = g_nUA = null;	// clear
/* Faster speed for other brower (& plateform?), 
avoid refresh or reload if nothing changes 
if you have the time! e.g. Safari... */

function listWords(value, open) {
	value = replaceOtherChars(value).trim();
	if (pages.length==0) {
		load();
	}
	var table = document.getElementById('result');
	while (table.rows.length > 0) {
		table.deleteRow(0);
	}
	firstLink=null;
	var clear = document.getElementById('clear'),
		trCheckBox = document.getElementById('trCheckBox'),
		trNextPrevButton = document.getElementById('trNextPrevButton');
	if (value.length == 0) {
		/* since user can now use next & previous button,
		allow text & highlighted screen to appear most of the time */
		var url = top.main.document.location.search;
		if (url.indexOf('?') < 0 && url.indexOf('#') < 0) {
			trCheckBox.style.display = 'none';
			trNextPrevButton.style.display = 'none';
			clear.style.display = 'none'; 
		}
		return true;
	}
	if (!g_isMSIE || g_IE7orBelow) {	// IE 8 or above lose these functionality
		// IE 8 & 9 refresh itself with only "#fndWord0" as URL parameter
		trCheckBox.style.display = '';
		trNextPrevButton.style.display = '';
	}
	clear.style.display = '';
	var keywords = value.split(' ');
	if (keywords.length > 1) {
		listAnd(keywords);
		return true;
	}
	if (value.length < 3) {
		max = 100;
	} else {
		max = 1000;
	}
	value = value.toLowerCase();
	var r = ref[value.charAt(0)];
	if (r==undefined) {
		return true;
	}
	var x=0;
	var words = r.split(';');
	var count=0;
	for (var i=0; i<words.length; i++) {
		var wordRef = words[i];
		if (wordRef.toLowerCase().indexOf(value)==0) {
			count++;
		}
	}
	for (var i=0; i<words.length && (x<=max); i++) {
		var wordRef = words[i];
		if (wordRef.toLowerCase().indexOf(value)==0) {
			word = wordRef.split("=")[0];
			var tr = table.insertRow(x++);
			var td = document.createElement('td');
			var tdc = document.createAttribute('class');
			tdc.nodeValue = 'searchKeyword';
			td.setAttributeNode(tdc);

			var ah = document.createElement('a');
			var hre = document.createAttribute('href');
			hre.nodeValue = 'javascript:set("' + word + '");';
			var link = document.createTextNode(word);
			ah.setAttributeNode(hre);
			ah.appendChild(link);
			td.appendChild(ah);
			tr.appendChild(td);
			pis = wordRef.split("=")[1].split(",");
			if (count<20 || open==word) {
				x = addReferences(x, pis, word);
			}
		}
	}
	if (x==0) {
		noResults(table);
	}
	return true;
}

function set(v) {
	if (pages.length==0) {
		load();
	}
	var searchElement = document.getElementById('search');
	listWords(searchElement.value, v);
	searchElement.focus();
	window.scrollBy(-20, 0);
}

function clearButton() {
	/* Assume: clear button clicked */
	document.getElementById('clear').style.display = 'none';
	document.getElementById('trNextPrevButton').style.display = 'none';
	document.getElementById('trCheckBox').style.display = 'none';
	// MUST clear previous g_highlight & g_searchValue
	g_highlight = "";
	g_searchValue = "";
	/* Have html page been highlighted? clear this.
	IE url e.g. ...\mypage.html#fndWord0
	Firefox url e.g. ...\mypage.html?highlight=tcp&mcase=false#fndWord0 */
	var page,
		location = top.main.document.location,
		url = location.href;	// do NOT use location.search!
	if (url.indexOf('?') > 0) {	// this is Firefox
		page = url.split('?')[0];
		location.href = page;
		markMainPageLoaded();
	} else if (url.indexOf('#') > 0) {
		page = url.split('#')[0];
		location.href = page;
		markMainPageLoaded();
	} /* else {page = url;} no need to clear screen */
}

function goFirst() {
	if (searchValueUpdated()) {
		var table = document.getElementById('result');
		if (firstLink != null) {
			go(firstLink, firstLinkWord);
		}
	}
	return false;
}

/**
 * Will update g_searchValue
 * @return true if search.value is updated
 */
function searchValueUpdated() {
	var searchValue = document.getElementById('search').value;
	if (searchValue != "" && searchValue != g_searchValue) {
		g_searchValue = searchValue;	// new search words
		return true;
	}
	return false;
}

function go(pageId, word) {
	var page = pages[pageId];
	searchValueUpdated();
	g_word = word;
	g_highlight = encodeURIComponent(replaceOtherChars(word +' '+ g_searchValue).split(' '));
	g_mcase = document.getElementById('mcase').checked;
	// always load the page via this dynamic link
	top.main.document.location.href = 
		"../"+ page.file +"?highlight="+ g_highlight +
		"&mcase="+ g_mcase +"#fndWord0";
	markMainPageLoaded();
}

/**
 * Mark an action was performed for main page to load.
 */
function markMainPageLoaded() {
	var e = document.getElementById("mainPageLoaded");
	if (e) e.value = new Date().getTime();
}

function goFindWord(move) {
	/* IE 7 or below when accessing other pages' URL doesn't have URL parameters, 
	i.e. top.main.document.location.href OR top.main.location.href OR
	top.main.document.location.URL OR top.main.location.URL 
	Such as "highlight" and "mcase" parameters, they're are missing */
	var location = top.main.document.location,
		noChange = true,
		url = location.href,	// do NOT use location.search!
		mcaseChecked = document.getElementById('mcase').checked;
	if (searchValueUpdated()) {
		// text box value now overides the original highlight word 
		// OR it could be word had never been highlighted
		g_highlight = encodeURIComponent(replaceOtherChars(
			(g_word.length ? g_word +' ' : '') + g_searchValue).split(' '));
		noChange = false;
	}
	if (g_highlight == "") return;
	if (mcaseChecked != g_mcase) {
		g_mcase = mcaseChecked;
		noChange = false;
	}
	var init = move >= 0 ? 0: -1, 
		newNum, page, param = "?highlight="+ g_highlight +"&mcase="+ mcaseChecked;
	if (url.lastIndexOf("#fndWord") > -1) {
		page = url.split("#fndWord");
		newNum = parseInt(page[1]);
		if (isNaN(newNum)) {
			newNum = init;
		} else {
			newNum += move;
		}
		page = page[0];
	} else {
		newNum = init;
		page = url;
		noChange = false;
	}
	//IE url e.g. ...\mypage.html#fndWord0
	//Firefox url e.g. ...\mypage.html?highlight=tcp&mcase=false#fndWord0
	if (url.indexOf('?') > -1) {	// this is Firefox or...
		page = url.split('?')[0];
	}
	if (noChange) newNum = getValidWordIdNum(newNum);	// getValidWordIdNum() from navigation.js
	else markMainPageLoaded();
	// else do NOT get valid number, page will reload with different highlight
	// highlight() will check if it's a valid number.
	if (g_isMSIE) {
		if (url.indexOf('file://') == 0) {	// local: IE behaviour is different from server!
			if (noChange) {	// no change, NO refresh
				page += "#fndWord"+ newNum;
			} else {
				// IE will ALWAYS refresh for local files if param highlight & mcase is present in URL 
				// i.e. ?highlight=tcp&mcase=false (params are needed 1st time)
				page += param +"#fndWord"+ newNum;
				markMainPageLoaded();
			}
		} else {	// server
			page += param +"#fndWord"+ newNum;
		}
	} else if (g_isFirefox || g_isMozilla || g_isOpera || g_isNetscape) {
		page += param +"#fndWord"+ newNum;
	} else {	// other browser NOT yet optimised
		// following should work for MOST browser however if it does NOT work 
		// change it so to force a reload
		page += param +"#fndWord"+ newNum;
		//Use this code to force a reload, highlight() will check if it's a valid number.
		//page += param +"&fndWord="+ newNum;
	}
	location.href = page;
}

function listAnd(keywords) {
	var count = [], weight = [];
	// fast reverse loop, each loop is less 1 comparison & length property access
	// e.g. for (var i = 0; i < pages.length; i++)
	for (var i=pages.length; i--;) {
		count[i] = 0;
		weight[i] = 0;
	}
	for (var i=0; i<keywords.length; i++) {
		var value = keywords[i].toLowerCase();
		var r = ref[value.charAt(0)];
		if (r==undefined) {
			return true;
		}
		var words = r.split(';');
		// fast reverse loop, each loop removed (j < words.length) comparison
		for (var j=words.length; j--;) {
			var wordRef = words[j];
			if (wordRef.toLowerCase().indexOf(value)==0) {
				pis = wordRef.split("=")[1].split(",");
				var w=1;
				for (var k=0; k<pis.length; k++) {
					var pi = pis[k];
					if (pi.charAt(0) == 't') {
						pi = pi.substring(1);
						w=10000;
					} else if (pi.charAt(0) == 'h') {
						pi = pi.substring(1);
						w=100;
					} else if (pi.charAt(0) == 'r') {
						pi = pi.substring(1);
						w=1;
					}
					if (count[pi]>=i) {
						if (count[pi]==i) {
							count[pi]++;
						}
						weight[pi]+=w;
					}
				}
			}
		}
	}
	var x = 0, 
		table = document.getElementById('result'),
		pis = [], 
		piw = [];
	// fast reverse loop, each loop removed (i < pages.length) comparison
	for (var i=pages.length; i--;) {
		if (count[i] >= keywords.length) {
			pis[x] = '' + i;
			piw[x] = weight[i];
			x++;
		}
	}
	// sort
	for (var i = 1, j; i < x; i++) {
		var tw = piw[i],
			ti = pis[i];
		for (j = i - 1; j >= 0 && (piw[j] < tw); j--) {
			piw[j + 1] = piw[j];
			pis[j + 1] = pis[j];
		}
		piw[j + 1] = tw;
		pis[j + 1] = ti;
	}
	addReferences(0, pis, keywords);
	if (pis.length == 0) {
		noResults(table);
	}
}

function addReferences(x, pis, word) {
	var table = document.getElementById('result');
	for (var j=0; j<pis.length; j++) {
		var pi = pis[j];
		if (pi.charAt(0) == 't') {
			pi = pi.substring(1);
		} else if (pi.charAt(0) == 'h') {
			pi = pi.substring(1);
		} else if (pi.charAt(0) == 'r') {
			pi = pi.substring(1);
		}
		var tr = table.insertRow(x++);
		var td = document.createElement('td');
		var tdc = document.createAttribute('class');
		tdc.nodeValue = 'searchLink';
		td.setAttributeNode(tdc);
		var ah = document.createElement('a');
		var hre = document.createAttribute('href');
		var thisLink = 'javascript:go(' + pi + ', "' + word + '")';
		if (firstLink==null) {
			firstLink = pi;
			firstLinkWord = word;
		}
		hre.nodeValue = thisLink;
		ah.setAttributeNode(hre);
		var page = pages[pi];
		var link = document.createTextNode(page.title);
		ah.appendChild(link);
		td.appendChild(ah);
		tr.appendChild(td);
	}
	return x;
}

function replaceOtherChars(s) {
	var x = "";
	// fast reverse loop, each loop removed (i < s.length) comparison
	for (var i = s.length; i--;) {
		var c = s.charAt(i);
		if ("\t\r\n\"'.,:;!&/\\?%@`[]{}()+-=<>|*^~#$".indexOf(c) >= 0) {
			c = " ";
		}
		x = c + x;
	}
	return x;
}

function noResults(table) {
	var tr = table.insertRow(0);
	var td = document.createElement('td');
	var tdc = document.createAttribute('class');
	tdc.nodeValue = 'searchKeyword';
	td.setAttributeNode(tdc);
	var text = document.createTextNode('No results found');
	td.appendChild(text);
	tr.appendChild(td);
}
